using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using System.Windows.Data;

namespace PlanetWPF.Toolbelt.Controls
{
    /// <summary>
    /// WeekNumberConverter uses current FirstDayOfWeek and DateTime to calculate the week numbers
    /// </summary>
    public sealed class WeekNumberConverter : IMultiValueConverter
    {
        /// <summary>
        /// calculate week number with FirstDayOfWeek and DateTime
        /// </summary>
        /// <param name="values">
        ///     values[0] : FirstDayOfWeek
        ///     values[1] : DateTime (this value is used to calculate the PowerMonthCalendar
        /// </param>
        /// <param name="targetType">int</param>
        /// <param name="parameter">0~5, row index of each month</param>
        /// <param name="culture">CultureInfo</param>
        /// <returns>week number, -1 if fails</returns>
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (values == null)
            {
                throw new ArgumentNullException("values");
            }

            if (values.Length != 2)
            {
                throw new ArgumentException("Wrong argument number.");
            }

            if (values[0] is DayOfWeek && values[1] is DateTime)
            {
                DayOfWeek firstDayOfWeek = (DayOfWeek)values[0];
                DateTime date = (DateTime)values[1];
                int offset = Int32.Parse((string)parameter, CultureInfo.InvariantCulture);

                DateTime firstVisibleDate = new DateTime(date.Year, date.Month, 1);
                DateTime lastVisibleDate = firstVisibleDate.AddMonths(1).AddSeconds(-1);

                int weekNumber = PowerCalendarDataGenerator.GetWeekNumber(date.Year, date.Month, firstDayOfWeek, culture.DateTimeFormat.CalendarWeekRule, offset, firstVisibleDate, lastVisibleDate);
                if (weekNumber != -1)
                {
                    return weekNumber;
                }
            }

            return -1;
        }

        /// <summary>
        /// Not Supported
        /// </summary>
        public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
}
